import { WHITELIST } from '@/plugins/api_whitelist'
const cancelTokenSources = new Map()

export default function({
  $axios,
  store,
  app: { $notification, i18n, router },
  redirect
}) {
  // 请求拦截
  $axios.onRequest(config => {
    if (
      !localStorage.getItem('token') &&
      !WHITELIST.some(val => val === config.url)
    ) {
      setTimeout(() => {
        redirect(401, '/login')
      }, 0)
      return Promise.reject(new Error('UNLOGIN'))
    }
    config.headers.lang = store.state.i18n.locale
    config.headers.token = localStorage.getItem('token') || ''
    const store_id = localStorage.getItem('store_id')
    if (store_id) {
      config.headers['store-id'] = store_id
    }

    const source = $axios.CancelToken.source()
    cancelTokenSources.set(source.token, source.cancel)
    config.cancelToken = source.token

    return config
  })

  // 响应拦截
  $axios.onResponse(response => {
    // 请求正常结束后移除
    const code = parseInt(response.data.code)
    switch (code) {
      case 1:
        cancelTokenSources.delete(response.config.cancelToken)
        return Promise.resolve(response.data)
      case 0:
        $notification.error({
          message: response.data.msg
        })
        cancelTokenSources.delete(response.config.cancelToken)
        return Promise.resolve(response.data)
      case -4:
        // 取消所有待响应请求
        for (const [token, cancel] of cancelTokenSources) {
          cancel(token)
        }
        localStorage.removeItem('token')
        setTimeout(() => {
          redirect(401, '/login')
        }, 0)
        // location.href = location.origin + '/login'
        return Promise.resolve(response.data)
      default:
        if (code !== 5) {
          $notification.error({
            message: response.data.msg
          })
        }
        cancelTokenSources.delete(response.config.cancelToken)
        return Promise.resolve(response.data)
    }
  })

  // 错误处理
  $axios.onError(error => {
    cancelTokenSources.delete(error.config.cancelToken)
    const code = parseInt(error.response && error.response.status)
    switch (code) {
      case 401:
        $notification.error({
          message: i18n.t('error.401'),
          description: error.message
        })
        break
      case 403:
        $notification.error({
          message: i18n.t('error.403'),
          description: error.message
        })
        break
      case 404:
        $notification.error({
          message: i18n.t('error.404'),
          description: error.message
        })
        break
      case 500:
        $notification.error({
          message: i18n.t('error.500'),
          description: error.message
        })
        break
    }
  })
  $axios.onResponseError(err => {
    return {
      code: 500,
      msg: err
    }
  })
}
